/* 
 * GrayRabbit Cms基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department：运营部
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.dao.category.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.dao.category.CategoryDao;
import org.grayrabbit.cms.dao.site.SiteDao;
import org.grayrabbit.cms.entity.Category;
import org.grayrabbit.cms.util.FilePathSptUtil;
import org.grayrabbit.cms.util.HqlUtil;
import org.grayrabbit.cms.vo.category.CategoryBean;
import org.grayrabbit.cms.vo.site.SiteBean;
import org.grayrabbit.dao.impl.GenericHibernateDao;
import org.grayrabbit.dao.util.Page;
import org.grayrabbit.dao.util.QueryCondition;
import org.hibernate.Criteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.opensymphony.xwork2.util.ArrayUtils;
 
/**
 * <b>Category</b> dao implementation 





 * @version 1.0，创建时间：2011-05-16 14:38:49 
 */
@Repository
public class CategoryDaoImpl extends GenericHibernateDao<Category, String>
		implements CategoryDao {

	private Logger LOG = LoggerFactory.getLogger(CategoryDaoImpl.class);
	/**
	 * HQL主体语句
	 */
	public static final String MAIN_HQL = "From Category as obj";
	/**
	 * HQL中count统计hql片段
	 */
	public static final String COUNT_HQL = "Select Count(obj) ";

	/**
	 * 根据bean组装查询条件
	 * @see CategoryDao#assembly(CategoryBean)
	 */
	public QueryCondition assembly(CategoryBean bean) {
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(bean!=null){
			if(!StringUtils.isNotBlank(bean.getCategoryId())){
				transNameQuery(bean,qc);
			}
		}
		return qc;
	}

	/**
	 * 根据bean组装统计查询条件
	 * @see CategoryDao#assemblyCount(CategoryBean)
	 */
	public QueryCondition assemblyCount(CategoryBean bean) {
		QueryCondition qc = new QueryCondition(COUNT_HQL + MAIN_HQL);
		transNameQuery(bean,qc);
		if(StringUtils.isNotBlank(bean.getCategoryId())){
			qc.add(" And obj.category.categoryId = ? ", bean.getCategoryId());
		 }
		return qc;
	}

	/**
	 * @see CategoryDao#count(CategoryBean)
	 */
	public int count(CategoryBean bean) {
		return ((Long)iterator(assemblyCount(bean)).next()).intValue();
	}

	/**
	 * 根据bean组装查询条件(名称参数)
	 * @see CategoryDao#assemblyNameQuery(CategoryBean)
	 */
	public QueryCondition assermblyNameQuery(CategoryBean bean) {
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		transNameQuery(bean, qc);
		return qc;
	}

	/**
	 * 根据bean组装统计查询条件(名称参数)
	 * @see CategoryDao#assemblyNameQueryCount(CategoryBean)
	 */
	public QueryCondition assemblyNameQueryCount(CategoryBean bean) {
		QueryCondition qc = new QueryCondition(COUNT_HQL + MAIN_HQL);
		transNameQuery(bean,qc);
		return qc;
	}

	/**
	 * 填充分页组件
	 * @see CategoryDao#findByPage(Page, CategoryBean)
	 */
	public List<Category> findByPage(Page<Category> page,CategoryBean bean) {
		QueryCondition qc = assembly(bean);
		qc.setMaxResults(-1);
		qc.setOffset(page.getOffset());
		if(StringUtils.isNotBlank(bean.getSite().getSiteId())){
			qc.add(" And obj.site.siteId = ? ", bean.getSite().getSiteId());
		}
		if(StringUtils.isNotBlank(bean.getCategoryId())){
			qc.add(" And obj.category.categoryId = ? ", bean.getCategoryId());
		 }else{
			 qc.append(" And obj.category.categoryId is null");
		 }
		qc.appenOrderBy("  obj.ord asc  ");
		qc.appenOrderBy("  obj.catName asc  ");
		 
		return findByQc(qc);
	}
	
	/**
	 * 查询所有记录
	 * @see SiteDao#findByPage(SiteBean)
	 */
	public List<Category> findByPage(
			CategoryBean bean) {
		QueryCondition qc = assembly(bean);
		return findByQc(qc);
	}
	/**
	 * 根据父Id查询记录（参数parentId，bean）
	 * @param siteBean
	 * @return 
	 */
	public List<Category> findByParentId(String parentId, CategoryBean categoryBean){
		QueryCondition qc = assembly(categoryBean);
		qc.add(" And obj.category.categoryId = ? ", parentId);
		return findByQc(qc);
	}
	/**
	 * 根据站点id查询栏目
	 * @param siteId
	 * @return
	 */
	public List<Category> findBySiteId(String siteId){
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		qc.add(" And obj.site.siteId = ? ", siteId);
		qc.appenOrderBy(" obj.ord asc");
		return findByQc(qc);
	}
	/**
	 * 根据序号查找记录
	 */
	public List<Category> findByOrd(Integer ord,CategoryBean bean){
		QueryCondition qc = assembly(bean);
		qc.add(" And obj.ord = ? ", ord);
		return findByQc(qc);
	}
	/**
	 * 检查栏目名称唯一性
	 */
	public Boolean checkNameUnique(String categoryName,String parentId,String siteId,String catname){
		boolean unique=false;
		List<Category> catList=null;
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(StringUtils.isNotBlank(categoryName)){
			qc.add(" And obj.catName =?", categoryName);
		}
		if(StringUtils.isNotBlank(parentId)){
			qc.add(" And obj.category.categoryId =?", parentId);
		}else{
			qc.append(" And obj.category.categoryId is null");
		}
		if(StringUtils.isNotBlank(siteId)){
			qc.add(" And obj.site.siteId = ?", siteId);
		}
		catList=findByQc(qc);
		if(StringUtils.isNotBlank(catname) && !catList.isEmpty()){
			for(int i=0;i<catList.size();i++){
				if(catList.get(i).getCatName().equals(catname)){
					catList.remove(i);
				}
			}
		}
		if((catList!=null)&&(!catList.isEmpty())){
			unique=true;
		}
		return unique;
	}
	/**
	 * 检查简称名称唯一性
	 * @param role
	 * @return
	 */
	public Boolean checksimpleunique(String catSimpleName,String siteId,String catoldSimpleName){
		List<Category> simplist=null;
		boolean unique=false;
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(StringUtils.isNotBlank(catSimpleName)){
			qc.add(" And obj.catSimpleName =?", catSimpleName);
		}
		if(StringUtils.isNotBlank(siteId)){
			qc.add("And obj.site.siteId=?",siteId);
		}
		simplist=findByQc(qc);
		if(StringUtils.isNotBlank(catoldSimpleName) && !simplist.isEmpty()){
			for(int i=0;i<simplist.size();i++){
				if(simplist.get(i).getCatSimpleName().equals(catoldSimpleName)){
					simplist.remove(i);
				}
				
			}
		}
		if((simplist!=null)&&(!simplist.isEmpty())){
			unique=true;
		}
		return unique;
		
	}
	/**
	 * 查询全部记录列表
	 * @return
	 */
	public List<Category> catList(String parentId,String siteId){
		List<Category> catList=null;
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(StringUtils.isNotBlank(parentId)){
			qc.add(" And obj.category.categoryId = ? ",parentId);
		}else{
			qc.append(" And obj.category.categoryId is null");
		}
		if(StringUtils.isNotBlank(siteId)){
			qc.add(" And obj.site.siteId = ? ", siteId);
		}
		qc.appenOrderBy("  obj.ord asc  ");
		qc.appenOrderBy("  obj.catName asc  ");
		
		catList=findByQc(qc);
		return catList;
	}
	/**
	 * 查询站点下所有栏目
	 * @return
	 */
	public List<Category>tailEndList(String siteId){
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(StringUtils.isNotBlank(siteId)){
			qc.add(" And obj.site.siteId = ?", siteId);
		}
		return findByQc(qc);
	}
	// 业务查询主要逻辑代码
	private void transNameQuery(CategoryBean bean,QueryCondition qc){
		if(bean!=null){
			if(StringUtils.isNotBlank(bean.getCatName())){
				qc.add("And obj.catName like ? ","%"+ bean.getCatName()+"%");
			}
			if(StringUtils.isNotBlank(bean.getCatSimpleName())){
				qc.add("And obj.catSimpleName like ? ", "%"+bean.getCatSimpleName()+"%");
			}
            if(bean.getCreateTime() != null){
				qc.add("And obj.createTime = ? ", bean.getCreateTime());
			}

            if(bean.getIsContribute() != null){
				qc.add("And obj.isContribute = ? ", bean.getIsContribute());
			}
            if(bean.getIsComment() != null){
				qc.add("And obj.isComment = ? ", bean.getIsComment());
			}
            if(bean.getIsInitComment() != null){
				qc.add("And obj.isInitComment = ? ", bean.getIsInitComment());
			}
            if(bean.getIsAudit() != null){
				qc.add("And obj.isAudit = ? ", bean.getIsAudit());
			}
            if(bean.getAuditor() != null){
				qc.add("And obj.auditor like ? ", bean.getAuditor()+"%");
			}
            if(bean.getSite()!=null&&StringUtils.isNotBlank(bean.getSite().getSiteId())){
            	qc.add(" And obj.site.siteId = ?", bean.getSite().getSiteId());
            }
		}
		qc.appenOrderBy("  obj.ord asc  ");
		qc.appenOrderBy("  obj.catName asc  ");
	}

	/** 顶级栏目
	 *
	 */
	public List<Category> findCat(String[] catIds,String[] siteIds) {
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		qc.append(" And obj.categoryStatus = 1 ");
		qc.append("And obj.category.categoryId is null") ;
		
		if(!ArrayUtils.isEmpty(catIds) && ArrayUtils.isEmpty(siteIds)){
			qc.append("And obj.categoryId in "+ HqlUtil.arraysToString(catIds));
		}else if(ArrayUtils.isEmpty(catIds) && !ArrayUtils.isEmpty(siteIds)){
			qc.append("And obj.site.siteId in "+ HqlUtil.arraysToString(siteIds));
		}else if(!ArrayUtils.isEmpty(catIds) && !ArrayUtils.isEmpty(siteIds)){
			qc.append(" And (");
			qc.append(" obj.site.siteId in "+ HqlUtil.arraysToString(siteIds));
			qc.append("or obj.categoryId in "+ HqlUtil.arraysToString(catIds));
			qc.append(" ) "); 
		}
		LOG.info(qc.toString());
		return findByQc(qc);
	}
	
	public List<Category> ftlFindSonCat(String catId){
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		qc.append(" And obj.categoryStatus = 1 ");
		if(StringUtils.isBlank(catId)) return new ArrayList<Category>();
		qc.add(" And obj.category.categoryId = ? ", catId);
		qc.appenOrderBy("  obj.ord asc  ");
		qc.appenOrderBy("  obj.catName asc  ");
		return findByQc(qc);
	}
	
	/**
	 * 获取站点下可发布的栏目
	 * @param siteId
	 * @param cat
	 * @return
	 */
	public List<String> findPublishCategoryBySiteId(List<String> siteIds,int currentCatIndex,int max){
		if(siteIds==null || siteIds.size()==0)
			return null;
		QueryCondition qc =new QueryCondition("Select obj.id "+MAIN_HQL);
		qc.append(" And obj.site.siteId in (");
		for(String siteId : siteIds){
			qc.add("?,", siteId);
		}
		qc.add("?","-1");//not exist
		qc.append(") ");
		qc.append(" And obj.categoryStatus = 1 ");
		qc.setOffset(currentCatIndex);
		qc.setMaxResults(max);
		qc.append("Order by obj.id asc ");
		return (List<String>) find(qc);
	}

	public List<Category> ftlFindByParentId(String catId) {
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		if(StringUtils.isNotBlank(catId)){			
			qc.add(" And obj.category.categoryId = ? ", catId);
		}
		qc.append(" And obj.categoryStatus = 1 ");
		qc.appenOrderBy("  obj.ord asc  ");
		qc.appenOrderBy("  obj.catName asc  ");
		return findByQc(qc);
	}
	
	public String getParentPath(Category obj){
		String path = obj.getCatSimpleName();
		if(obj.getCategory()!=null){
			if(findById(obj.getCategory().getCategoryId())!=null){
				path=FilePathSptUtil.padRightSpt(getParentPath(findById(obj.getCategory().getCategoryId())))+path;
			}
		}
		return path;
	}
	
	public List<Category> ftlFindTopCategory(String siteid){
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		qc.append(" And obj.category.categoryId is null ");
		qc.append(" And obj.categoryStatus = 1");
		if(StringUtils.isNotBlank(siteid)){
			qc.add(" And obj.site.siteId = ? ",siteid);
		}
		qc.appenOrderBy(" obj.ord asc");
		List<Category> list = findByQc(qc);
		return list;
	}
	/**
	 * 得到顶级栏目
	 * @param siteId
	 * @return
	 */
	public List<Category> getTopCategory(String siteId){
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		qc.append(" And obj.category.categoryId is null ");
		qc.append(" And obj.categoryStatus = 1");
		if(StringUtils.isNotBlank(siteId)){
			qc.add("  And obj.site.siteId = ?", siteId);
		}
		qc.appenOrderBy(" obj.site.siteId asc");
		qc.appenOrderBy(" obj.ord asc");
		return findByQc(qc);
	}
	
	public Category getHomeCategory(String siteId){
		try{
			if(StringUtils.isBlank(siteId))
				throw new IllegalArgumentException("the argument 'siteId' is null,error!");
			QueryCondition qc =new QueryCondition(MAIN_HQL);
			qc.append(" And obj.category.categoryId is null ");
			qc.append(" And obj.categoryStatus = 1");
			qc.add("  And obj.site.siteId = ?", siteId);
			qc.appenOrderBy(" obj.ord asc");
			List<Category> list = findByQc(qc);
			return list.get(0);
		}catch(Exception e){
			logger.error("获取栏目异常:{}",e);
		}
		return new Category();
	}
	
	public List<Category> ftlFindCategory(String siteid, String categoryid, long[] limit){
		QueryCondition qc =new QueryCondition(MAIN_HQL);
		if(StringUtils.isBlank(categoryid)){
			qc.append(" And obj.category.categoryId is null ");
		}else{
			qc.add(" And obj.category.categoryId = ? ",categoryid);
		}
		qc.append(" And obj.categoryStatus = 1 ");
		qc.add("  And obj.site.siteId = ?", siteid);
		if(!org.apache.commons.lang.ArrayUtils.isEmpty(limit) && limit.length < 3){
			if(limit.length==1){
				qc.setMaxResults((int) limit[0]);
				qc.setOffset(0);
			}
			if (limit.length == 2) {
				qc.setMaxResults((int) limit[1]);
				qc.setOffset((int) limit[0]);
			}
		}
		qc.appenOrderBy(" obj.ord asc");
		List<Category> list = findByQc(qc);
		return list;
	}
	
	public List<Category> findRollannounceCat(String[] siteId, String rollannounceSimpleName) {
		QueryCondition qc = new QueryCondition(MAIN_HQL);
		if(!ArrayUtils.isEmpty(siteId) && StringUtils.isNotBlank(rollannounceSimpleName)) {
			qc.append(" And obj.site in " + HqlUtil.arraysToString(siteId));
			qc.append(" And obj.catSimpleName = '"+rollannounceSimpleName.trim()+"'");
			return findByQc(qc);
		}
		return new ArrayList<Category>();
	}

	public String findCatIdByCatName(String catName,String catShortname,String siteId,String siteArea) {
		Criteria criteria = getSession().createCriteria(Category.class);
		if(StringUtils.isNotBlank(catName)) 
			criteria.add(Restrictions.eq("catName", catName));
		if(StringUtils.isNotBlank(catShortname)) 
			criteria.add(Restrictions.eq("catSimpleName", catShortname));
		if(StringUtils.isNotBlank(siteId)) 
			criteria.add(Restrictions.eq("site.siteId", siteId));
		if(StringUtils.isNotBlank(siteArea)){
			criteria.createAlias("site", "site");
			criteria.add(Restrictions.eq("site.area", siteArea));
		} 
		criteria.add(Restrictions.eq("categoryStatus", Boolean.TRUE));
		criteria.setProjection(Projections.property("categoryId"));
		criteria.setMaxResults(1);
		return (String)criteria.uniqueResult();
	}

	public Category findByNameAndSiteArea(String catName, String area) {
		Criteria criteria = getSession().createCriteria(Category.class);
		if(StringUtils.isNotBlank(catName)) 
			criteria.add(Restrictions.eq("catName", catName));	
		if(StringUtils.isNotBlank(area)) {
			criteria.createAlias("site", "site");
			criteria.add(Restrictions.eq("site.area", area));
			criteria.add(Restrictions.eq("site.siteStatus", Boolean.TRUE));
		}
		criteria.add(Restrictions.eq("categoryStatus", Boolean.TRUE));
		criteria.setMaxResults(1);
		return (Category)criteria.uniqueResult();
	}
}